home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Online / opennap / userdb.c < prev    next >
C/C++ Source or Header  |  2001-06-08  |  5KB  |  261 lines

  1. /* Copyright (C) 2000-1 drscholl@users.sourceforge.net
  2.    This is free software distributed under the terms of the
  3.    GNU Public License.  See the file COPYING for details.
  4.  
  5.    $Id: userdb.c,v 1.31 2001/02/15 08:39:45 drscholl Exp $ */
  6.  
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <errno.h>
  12. #include <limits.h>
  13. #include <time.h>
  14. #ifndef WIN32
  15. #include <unistd.h>
  16. #endif
  17. #include <limits.h>
  18. #include "opennap.h"
  19. #include "debug.h"
  20.  
  21. HASH   *User_Db = 0;
  22.  
  23. int
  24. get_level (const char *s)
  25. {
  26.     if (!strncasecmp ("lee", s, 3))
  27.     return LEVEL_LEECH;
  28.     if (!strncasecmp ("use", s, 3))
  29.     return LEVEL_USER;
  30.     if (!strncasecmp ("mod", s, 3))
  31.     return LEVEL_MODERATOR;
  32.     if (!strncasecmp ("eli", s, 3))
  33.     return LEVEL_ELITE;
  34.     if (!strncasecmp ("adm", s, 3))
  35.     return LEVEL_ADMIN;
  36.     return -1;
  37. }
  38.  
  39. void
  40. userdb_free (USERDB * p)
  41. {
  42.     if (p)
  43.     {
  44.     if (p->nick)
  45.         FREE (p->nick);
  46. #if EMAIL
  47.     if (p->email)
  48.         FREE (p->email);
  49. #endif
  50.     if (p->password)
  51.         FREE (p->password);
  52.     FREE (p);
  53.     }
  54. }
  55.  
  56. int
  57. userdb_init (void)
  58. {
  59.     FILE   *fp;
  60.     int     ac, regen = 0, level;
  61.     char   *av[7], path[_POSIX_PATH_MAX];
  62.     USERDB *u;
  63.  
  64.     snprintf (path, sizeof (path), "%s/users", Config_Dir);
  65.     fp = fopen (path, "r");
  66.     if (!fp)
  67.     {
  68.     logerr ("userdb_init", path);
  69.     return -1;
  70.     }
  71.     User_Db = hash_init (257, (hash_destroy) userdb_free);
  72.     log ("userdb_init(): reading %s", path);
  73.     if (fgets (Buf, sizeof (Buf), fp))
  74.     {
  75.     if (strncmp (":version 1", Buf, 10))
  76.     {
  77.         regen = 1;
  78.         rewind (fp);
  79.     }
  80.     }
  81.     while (fgets (Buf, sizeof (Buf), fp))
  82.     {
  83.     ac = split_line (av, FIELDS (av), Buf);
  84.     if (ac >= 6)
  85.     {
  86.         if (invalid_nick (av[0]))
  87.         {
  88.         log ("userdb_init(): %s: invalid nickname", av[0]);
  89.         continue;
  90.         }
  91.         u = CALLOC (1, sizeof (USERDB));
  92.         if (u)
  93.         {
  94.         u->nick = STRDUP (av[0]);
  95.         if (regen)
  96.             u->password = generate_pass (av[1]);
  97.         else
  98.             u->password = STRDUP (av[1]);
  99. #if EMAIL
  100.         u->email = STRDUP (av[2]);
  101. #endif
  102.         }
  103.         if (!u || !u->nick || !u->password
  104. #if EMAIL
  105.         || !u->email
  106. #endif
  107.         )
  108.         {
  109.         OUTOFMEMORY ("userdb_init");
  110.         if (u)
  111.             userdb_free (u);
  112.         fclose (fp);
  113.         return -1;
  114.         }
  115.         level = get_level (av[3]);
  116.         if (level < 0 || level > LEVEL_ELITE)
  117.         {
  118.         log ("userdb_init(): invalid level %s for user %s", av[3],
  119.              u->nick);
  120.         level = LEVEL_USER;
  121.         }
  122.         u->level = level;
  123.         u->created = atol (av[4]);
  124.         u->lastSeen = atol (av[5]);
  125.         if (ac > 6)
  126.         u->flags = atoi (av[6]);    /* u_short, atoi() is fine */
  127.         hash_add (User_Db, u->nick, u);
  128.     }
  129.     else
  130.     {
  131.         log ("userdb_init(): bad user db entry");
  132.         print_args (ac, av);
  133.     }
  134.     }
  135.     fclose (fp);
  136.     log ("userdb_init: %d registered users", User_Db->dbsize);
  137.     /* reformat to version 1 specification */
  138.     if (regen)
  139.     userdb_dump ();
  140.     return 0;
  141. }
  142.  
  143. static void
  144. dump_userdb (USERDB * db, FILE * fp)
  145. {
  146.     if (global.current_time - db->lastSeen >= Nick_Expire)
  147.     {
  148.     if (db->level < LEVEL_MODERATOR)
  149.     {
  150.         strcpy (Buf, ctime (&db->lastSeen));
  151.         Buf[strlen (Buf) - 1] = 0;
  152.         log ("dump_userdb: %s has expired (last seen %s)", db->nick,
  153.          Buf);
  154.         hash_remove (User_Db, db->nick);
  155.         return;
  156.     }
  157.     /* warn, but dont nuke expired accounts for privileged users */
  158.     log ("dump_userdb: %s has expired (ignored: level=%s)",
  159.          db->nick, Levels[db->level]);
  160.     }
  161.  
  162.     fputs (db->nick, fp);
  163.     fputc (' ', fp);
  164.     fputs (db->password, fp);
  165.     fputc (' ', fp);
  166. #if EMAIL
  167.     fputs (db->email, fp);
  168. #else
  169.     fputs ("unknown", fp);    /* dummy value to keep file format the same */
  170. #endif
  171.     fputc (' ', fp);
  172.     fputs (Levels[db->level], fp);
  173.     fputc (' ', fp);
  174.     fprintf (fp, "%d %u %hu", (int) db->created, (int) db->lastSeen,
  175.          db->flags);
  176. #ifdef WIN32
  177.     fputs ("\r\n", fp);
  178. #else
  179.     fputc ('\n', fp);
  180. #endif
  181. }
  182.  
  183. int
  184. userdb_dump (void)
  185. {
  186.     FILE   *fp;
  187.     char    path[_POSIX_PATH_MAX], tmppath[_POSIX_PATH_MAX];
  188.  
  189.     log ("userdb_dump(): dumping user database");
  190.     snprintf (tmppath, sizeof (tmppath), "%s/users.tmp", Config_Dir);
  191.     fp = fopen (tmppath, "w");
  192.     if (!fp)
  193.     {
  194.     logerr ("userdb_dump", tmppath);
  195.     return -1;
  196.     }
  197. #ifdef WIN32
  198.     fputs (":version 1\r\n", fp);
  199. #else
  200.     fputs (":version 1\n", fp);
  201. #endif
  202.     hash_foreach (User_Db, (hash_callback_t) dump_userdb, fp);
  203.     if (fflush (fp))
  204.     {
  205.     logerr ("userdb_dump", "fflush");
  206.     fclose (fp);
  207.     return -1;
  208.     }
  209.     if (fclose (fp))
  210.     {
  211.     logerr ("userdb_dump", "fclose");
  212.     return -1;
  213.     }
  214.     snprintf (path, sizeof (path), "%s/users", Config_Dir);
  215.     if (unlink (path))
  216.     logerr ("userdb_dump", "unlink");    /* not fatal, may not exist */
  217.     if (rename (tmppath, path))
  218.     {
  219.     logerr ("userdb_dump", "rename");
  220.     return -1;
  221.     }
  222.     log ("userdb_dump: wrote %d entries", User_Db->dbsize);
  223.     return 0;
  224. }
  225.  
  226. /* create a default USERDB record from the existing user */
  227. USERDB *
  228. create_db (USER * user)
  229. {
  230.     USERDB *db = CALLOC (1, sizeof (USERDB));
  231.  
  232.     if (db)
  233.     {
  234.     db->nick = STRDUP (user->nick);
  235.     db->password = generate_pass (user->pass);
  236. #if EMAIL
  237.     snprintf (Buf, sizeof (Buf), "anon@%s", Server_Name);
  238.     db->email = STRDUP (Buf);
  239. #endif
  240.     db->level = user->level;
  241.     db->created = global.current_time;
  242.     db->lastSeen = global.current_time;
  243.     }
  244.     if (!db || !db->nick || !db->password
  245. #if EMAIL
  246.     || !db->email
  247. #endif
  248.     )
  249.     {
  250.     OUTOFMEMORY ("create_db");
  251.     userdb_free (db);
  252.     return 0;
  253.     }
  254.     if (hash_add (User_Db, db->nick, db))
  255.     {
  256.     userdb_free (db);
  257.     return 0;
  258.     }
  259.     return db;
  260. }
  261.